import random
import socket
import struct
import hashlib


class TlvParse(object):
    ver = 2
    pap_chap = 1
    rsvd = 0
    req_id = 0
    user_port = 0
    err_code = 0

    # data{"username":zyt,"pwd":"123456"} secret = "123456789"
    def get_online_data(self, data, secret):
        p_type = 3
        return self.get_data(p_type, data, secret)

    def get_offline_data(self, data, secret):
        p_type = 5
        return self.get_data(p_type, data, secret)

    def get_data(self, p_type, data, secret):
        serial_no = random.randint(0, 65535)
        # 本机IP
        # user_ip = self.ip_parser(socket.gethostbyname(socket.gethostname()))
        user_ip = self.ip_parser("192.168.1.190")
        attr_num = len(data)
        dLen1 = len(data["username"].encode("utf-8")) + 2
        dLen2 = len(data["password"].encode("utf-8")) + 2
        sLen = len(secret.encode("utf-8"))
        fmt = "BBBBHHBBBBHBBQQBB" + str(dLen1 - 2) + "sBB" + str(dLen2 - 2) + "s" + str(sLen) + "s"
        print("auth_fmt:%s" % fmt)
        auth = self.create_md5_auth(
            struct.pack(fmt, self.ver, p_type, self.pap_chap, self.rsvd, serial_no, self.req_id, int(user_ip[0]),
                        int(user_ip[1]), int(user_ip[2]), int(user_ip[3]), self.user_port, self.err_code, attr_num, 0,
                        0, 1, dLen1, data["username"].encode("utf-8"), 2, dLen2, data["password"].encode("utf-8"),
                        secret.encode("utf-8")))
        print("auth:%s" % auth)
        fmt = "BBBBHHBBBBHBB16sBB" + str(dLen1 - 2) + "sBB" + str(dLen2 - 2) + "s"
        print("data_fmt:%s" % fmt)
        result = struct.pack(fmt, self.ver, p_type, self.pap_chap, self.rsvd, serial_no, self.req_id, int(user_ip[0]),
                             int(user_ip[1]), int(user_ip[2]), int(user_ip[3]),
                             self.user_port, self.err_code, attr_num, auth, 1, dLen1,
                             data["username"].encode("utf-8"), 2, dLen2, data["password"].encode("utf-8"))
        print(
            "ver:%s\ntype:%s\npap_chap:%s\nrsvd:%s\nserial_no:%s\nreq_id:%s\nuser_ip:%s.%s.%s.%s\nuser_port:%s\nerr_code:%s\nattr_num:%s\nauth:%s\nattr:%s\nsecret:%s" % (
                self.ver, p_type, self.pap_chap, self.rsvd, serial_no, self.req_id, int(user_ip[0]),
                int(user_ip[1]), int(user_ip[2]), int(user_ip[3]), self.user_port, self.err_code, attr_num, auth, data,
                secret))
        return result

    def create_md5_auth(self, data):
        m = hashlib.md5()
        m.update(data)
        return m.digest()

    def ip_parser(self, ip):
        return ip.split('.')

    def tlv_result_parser(self, data):
        result = False
        if data[14] == 4:
            result = True
        return result


if __name__ == "__main__":
    data = {}
    data["username"] = "zyt"
    data["password"] = "123456"
    secret = "123456789"
    print(TlvParse().get_online_data(data, secret))
